import os

"""

os.access() 方法使用当前的uid/gid尝试访问路径。大部分操作使用有效的 uid/gid, 因此运行环境可以在 suid/sgid 环境尝试。

语法格式：
    os.access(path, mode);

    path -- 要用来检测是否有访问权限的路径。
    mode -- mode为F_OK，测试存在的路径，或者它可以是包含R_OK, W_OK和X_OK或者R_OK, W_OK和X_OK其中之一或者更多。
        os.F_OK: 作为access()的mode参数，测试path是否存在。
        os.R_OK: 包含在access()的mode参数中 ， 测试path是否可读。
        os.W_OK 包含在access()的mode参数中 ， 测试path是否可写。
        os.X_OK 包含在access()的mode参数中 ，测试path是否可执行。
"""
filepath = "/etc/profile"
ret = os.access(filepath, os.F_OK)
print("F_OK - return %s" % ret)

ret = os.access(filepath, os.R_OK)
print("R_OK - return %s" % ret)

ret = os.access(filepath, os.W_OK)
print("W_OK - return %s" % ret)

ret = os.access(filepath, os.X_OK)
print("X_OK - return %s" % ret)

# 存在并且可读
ret = os.access(filepath, os.F_OK | os.R_OK)
print("os.F_OK | os.R_OK - return %s" % ret)

# 存在并且可写
ret = os.access(filepath, os.F_OK | os.W_OK)
print("os.F_OK | os.W_OK - return %s" % ret)

"""
Python3 File(文件) 方法
file 对象使用 open 函数来创建，下表列出了 file 对象常用的函数
"""

"""
打开一个文件
open(filename, mode):file

    filename：filename 变量是一个包含了你要访问的文件名称的字符串值。
    mode：mode决定了打开文件的模式：只读，写入，追加等。所有可取值见如下的完全列表。这个参数是非强制的，默认文件访问模式为只读(r)。
    
        只读取模式
        r	以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
        rb	以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
        r+	打开一个文件用于读写。文件指针将会放在文件的开头。
        rb+	以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
        
        下面的方法调用时如果该文件不存在，创建新文件。如果该文件已存在则将其覆盖。
        w	打开一个文件只用于写入。          
        wb	以二进制格式打开一个文件只用于写入。
        w+	打开一个文件用于读写。
        wb+	以二进制格式打开一个文件用于读写。
        
        ~~~,文件指针将会放在文件的结尾,即新的内容将会被写入到已有内容之后。
        a	打开一个文件用于追加。如果该文件已存在。
        ab	以二进制格式打开一个文件用于追加。
        a+	打开一个文件用于读写。
        ab+	以二进制格式打开一个文件用于追加。
        
        模式	        r	r+	w	w+	a	a+
        读	        +	+		+		+
        写		        +	+	+	+	+
        创建			        +	+	+	+
        覆盖			        +	+		
        指针在开始	+	+	+	+		
        指针在结尾					+	+

f.tell():int 
获取文件对象当前所处的位置, 它是从文件开头开始算起的字节数。
注意：字节数不等同于字符数目，因为中文由多个字节组成

"""
filepath = "runtime/foo.txt"
f = open(filepath, "w")
num = f.write("Python\n")
pos = f.tell()
num += f.write("非常好!\n")
f.close()
print('There are %d characters wrote into file,now the position is %d' % (num, pos))
"""
读取文件
file.read(size=-1):string
为了读取一个文件的内容，调用 f.read(size), 这将读取一定数目的数据, 然后作为字符串或字节对象返回。

size 是一个可选的数字类型的参数。 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回。

以下实例假定文件 foo.txt 已存在（上面实例中已创建）：
"""
f = open(filepath, 'r')
print('content:', f.read(), sep="\n")
f.close()
"""
读取一行
f.readline() 会从文件中读取单独的一行。换行符为 '\n'。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。
"""
i = 1
f = open(filepath, 'r')
while True:
    line = f.readline()
    if line:
        # 后面的 \n 也会带上
        print("Line %d content:%s" % (i, line), end='')
        i += 1
    else:
        print('end of file')
        break
f.close()
"""
读取所有行
f.readlines() 将返回该文件中包含的所有行。
如果设置可选参数 sizehint, 则读取指定长度的字节, 并且将这些字节按行分割。
"""
f = open(filepath, "r")
lines = f.readlines()
print("Lines are %s:" % repr(lines))
f.close()
"""
f.seek(offset, from_what)
改变文件当前的位置,。
    from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾，例如：
        seek(x,0) ： 从起始位置即文件首行首字符开始移动 x 个字符
        seek(x,1) ： 表示从当前位置往后移动x个字符
        seek(-x,2)： 表示从文件的结尾往前移动x个字符
    from_what 值为默认为0，即文件开头。
    
抛出下列错误：
Traceback (most recent call last):
  File "16.os.py", line 138, in <module>
    f.seek(1, 1)
io.UnsupportedOperation: can't do nonzero cur-relative seeks
原因：
以文本形式打开时，只能使用模式0
In text files (those opened without a b in the mode string), only seeks relative to the beginning of the 
file are allowed (the exception being seeking to the very file end with seek(0, 2)).
"""
f = open(filepath, "r+")
print("seek begin content is :", f.read())
f.seek(1, 0)
f.write("_")
# f.seek(1, 1)
# f.write("__")
# f.seek(1, 2)
# f.write("___")

f.seek(0, 0)
print("seek end content is :", f.read())
f.close()
"""
file.close():void
close() 方法用于关闭一个已打开的文件。关闭后的文件不能再进行读写操作， 否则会触发 ValueError 错误。 close() 方法允许调用多次。

当 file 对象，被引用到操作另外一个文件时，Python 会自动关闭之前的 file 对象。 使用 close() 方法关闭文件是一个好的习惯。
"""
